package com.start.form.engine.store.mysql.mapper;

import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.start.common.constant.StartConstant;
import com.start.common.dataRule.StartQueryWrapper;
import com.start.form.engine.core.model.StartFormColumnModel;
import com.start.form.engine.core.entity.StartFormConfig;
import com.start.form.engine.core.model.StartFormData;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

@Mapper
public interface SqlTableDataStorageMapper {
    String TABLE_SELECT_SQL = " select  " +
            "        <foreach collection=\"column\" item=\"item\" separator=\",\">  " +
            "            ${item.prop}  " +
            "        </foreach>  " +
            "        from ${tableName} ";

    /**
     * 数据精度SQL拼接
     */
    String COL_NUMBER_PRECISION = "<if test=\"column.precision!=null and column.precision>0\">,${column.precision}</if>";

    @InterceptorIgnore(tenantLine = "true")
    @Select(" SELECT column_name    id," +
            " column_name    prop," +
            " column_comment label," +
            " column_type sql_column_type " +
            " FROM information_schema.COLUMNS" +
            " WHERE table_name = #{tableName}" +
            " AND table_schema = (SELECT DATABASE())" +
            " ORDER BY ordinal_position")
    List<StartFormColumnModel> getTableColumns(@Param("tableName") String tableName);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START + TABLE_SELECT_SQL + " ${ew.customSqlSegment}" + StartConstant.MBP_SCRIPT.END)
    Page<Map<String, Object>> pageStorage(@Param("page") Page<Map<String, Object>> page,
                                          @Param("tableName") String tableName,
                                          @Param("column") List<StartFormColumnModel> columns,
                                          @Param(Constants.WRAPPER) StartQueryWrapper query);

    @InterceptorIgnore(tenantLine = "true")
    @Select("SELECT tables.TABLE_NAME      AS table_name," +
            "  tables.ENGINE          AS engine_name," +
            "  tables.TABLE_COMMENT   AS table_comment," +
            "  tables.TABLE_COLLATION AS table_collation," +
            "  tables.CREATE_TIME     AS create_time," +
            "  tables.TABLE_SCHEMA    AS table_schema" +
            "  FROM information_schema.TABLES" +
            "  where table_schema = (select dataBase())" +
            "  AND tables.TABLE_NAME = #{tableName} limit 1")
    Map<String, String> getTableByTableName(@Param("tableName") String tableName);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START + TABLE_SELECT_SQL + "  ${ew.customSqlSegment}" + StartConstant.MBP_SCRIPT.END)
    List<Map<String, Object>> storageList(@Param("tableName") String tableName,
                                          @Param("column") List<StartFormColumnModel> column,
                                          @Param(Constants.WRAPPER) StartQueryWrapper query);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START +
            " ALTER TABLE ${tableName}  " +
            " ADD COLUMN ${column.prop} ${column.sqlType}  " +
            " <if test=\"column.sqlTypeDataLength!=null and column.sqlTypeDataLength>0\">(${column.sqlTypeDataLength}" + COL_NUMBER_PRECISION + ")</if>  " +
            " <if test=\"column.label!=null and column.label.length>0\">COMMENT #{column.label}</if>;" + StartConstant.MBP_SCRIPT.END)
    void addColumn(@Param("tableName") String tableName, @Param("column") StartFormColumnModel column);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START +
            " ALTER TABLE ${tableName} CHANGE ${column.oldProp} ${column.prop} ${column.sqlType}  " +
            " <if test=\"column.sqlTypeDataLength!=null and column.sqlTypeDataLength>0\">(${column.sqlTypeDataLength}" + COL_NUMBER_PRECISION + ")</if>  " +
            " <if test=\"column.label!=null and column.label.length>0\">COMMENT #{column.label}</if>; " + StartConstant.MBP_SCRIPT.END)
    void updateColumn(@Param("tableName") String tableName, @Param("column") StartFormColumnModel column);


    @Delete("ALTER TABLE ${tableName} DROP COLUMN ${column.prop}; ")
    void deleteColumn(@Param("tableName") String tableName, @Param("column") StartFormColumnModel column);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START + "" +
            "  insert into ${tableName}  " +
            "        <foreach collection=\"columnData\" item=\"data\" separator=\",\" close=\")\" open=\"(\">  " +
            "            ${data.prop}  " +
            "        </foreach>  " +
            "        values  " +
            "        <foreach collection=\"columnData\" item=\"data\" separator=\",\" close=\")\" open=\"(\">  " +
            "            #{data.dataValue}  " +
            "        </foreach>" + StartConstant.MBP_SCRIPT.END)
    void storageSave(@Param("tableName") String tableName, @Param("columnData") List<StartFormData> columnData);


    @Select(StartConstant.MBP_SCRIPT.START +
            "UPDATE ${tableName} SET  " +
            "        <foreach collection=\"columnData\" item=\"data\" separator=\",\">  " +
            "            ${data.prop}= #{data.dataValue}  " +
            "        </foreach>  " +
            "        ${ew.customSqlSegment}" + StartConstant.MBP_SCRIPT.END)
    Long storageUpdate(@Param("tableName") String tableName,
                       @Param("columnData") List<StartFormData> columnData,
                       @Param(Constants.WRAPPER) StartQueryWrapper query);

    @InterceptorIgnore(tenantLine = "true")
    @Delete("DROP TABLE ${tableName}")
    void deleteTable(@Param("tableName") String tableName);

    @InterceptorIgnore(tenantLine = "true")
    @Delete("DELETE FROM ${tableName}")
    void clearData(@Param("tableName") String tableName);

    @InterceptorIgnore(tenantLine = "true")
    @Select(StartConstant.MBP_SCRIPT.START +
            "  CREATE TABLE ${formConfig.tableName} (  " +
            "        <foreach collection=\"columns\" item=\"column\" separator=\",\">  " +
            "            ${column.prop} ${column.sqlType}  " +
            "            <if test=\"column.sqlTypeDataLength!=null and column.sqlTypeDataLength>0\">" +
            "               (${column.sqlTypeDataLength}" + COL_NUMBER_PRECISION + "             )" +
            "            </if>  " +
            "            <if test=\"column.label!=null and column.label.length>0\">COMMENT #{column.label}</if>  " +
            "        </foreach>,  " +
            "        PRIMARY KEY (id))  " +
            "        <if test=\"formConfig.name!=null and formConfig.name.length>0\">COMMENT=#{formConfig.name}</if>  " + StartConstant.MBP_SCRIPT.END)
    Long createTable(@Param("formConfig") StartFormConfig formConfig, @Param("columns") List<StartFormColumnModel> columns);

    @InterceptorIgnore(tenantLine = "true")
    @Update(" alter table ${formConfig.tableName} comment #{formConfig.name} ")
    void updateTableComment(@Param("formConfig") StartFormConfig formConfig);


    @Select("  delete from ${tableName} ${ew.customSqlSegment} ")
    Long storageRemove(@Param("tableName") String tableName, @Param(Constants.WRAPPER) StartQueryWrapper queryWrapper);


    @Select(" select count(*)  from ${tableName} ${ew.customSqlSegment} ")
    Long storageCount(@Param("tableName") String tableName, @Param(Constants.WRAPPER) StartQueryWrapper queryWrapper);
}
